/*
 * Copyright (c) 2005-2009 Substance Kirill Grouchnikov. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  o Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  o Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  o Neither the name of Substance Kirill Grouchnikov nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package scribd.lookandfeel;

import java.awt.*;
import java.awt.image.BufferedImage;

import javax.swing.JScrollBar;

import org.jvnet.flamingo.common.AbstractCommandButton;
import org.jvnet.substance.SubstanceLookAndFeel;
import org.jvnet.substance.api.SubstanceColorScheme;
import org.jvnet.substance.painter.decoration.DecorationAreaType;
import org.jvnet.substance.painter.decoration.SubstanceDecorationPainter;
import org.jvnet.substance.painter.gradient.StandardGradientPainter;
import org.jvnet.substance.painter.gradient.SubstanceGradientPainter;

public class CookbookGradientPainter implements SubstanceGradientPainter {
	private SubstanceGradientPainter delegate;

	private SubstanceGradientPainter flatDelegate;

	private class CookbookDelegateGradientPainter extends
			StandardGradientPainter {
		@Override
		public Color getTopShineColor(
				SubstanceColorScheme interpolationScheme1,
				SubstanceColorScheme interpolationScheme2, double cycleCoef,
				boolean useCyclePosAsInterpolation) {
			return null;
		}

		@Override
		public Color getBottomShineColor(
				SubstanceColorScheme interpolationScheme1,
				SubstanceColorScheme interpolationScheme2, double cycleCoef,
				boolean useCyclePosAsInterpolation) {
			return null;
		}

		@Override
		public Color getTopFillColor(SubstanceColorScheme interpolationScheme1,
				SubstanceColorScheme interpolationScheme2, double cycleCoef,
				boolean useCyclePosAsInterpolation) {
			if (!useCyclePosAsInterpolation)
				return interpolationScheme1.getExtraLightColor();
			return CookbookSkin.getInterpolatedRGB(interpolationScheme1
					.getExtraLightColor(), interpolationScheme2
					.getExtraLightColor(), cycleCoef);
		}

		@Override
		public Color getMidFillColorTop(
				SubstanceColorScheme interpolationScheme1,
				SubstanceColorScheme interpolationScheme2, double cycleCoef,
				boolean useCyclePosAsInterpolation) {
			if (!useCyclePosAsInterpolation)
				return interpolationScheme1.getMidColor();
			return CookbookSkin.getInterpolatedRGB(interpolationScheme1
					.getMidColor(), interpolationScheme2.getMidColor(),
					cycleCoef);
		}

		@Override
		public Color getMidFillColorBottom(
				SubstanceColorScheme interpolationScheme1,
				SubstanceColorScheme interpolationScheme2, double cycleCoef,
				boolean useCyclePosAsInterpolation) {
			return this
					.getMidFillColorTop(interpolationScheme1,
							interpolationScheme2, cycleCoef,
							useCyclePosAsInterpolation);
		}

		@Override
		public Color getBottomFillColor(
				SubstanceColorScheme interpolationScheme1,
				SubstanceColorScheme interpolationScheme2, double cycleCoef,
				boolean useCyclePosAsInterpolation) {
			if (!useCyclePosAsInterpolation)
				return interpolationScheme1.getUltraDarkColor();
			return CookbookSkin.getInterpolatedRGB(interpolationScheme1
					.getUltraDarkColor(), interpolationScheme2
					.getUltraDarkColor(), cycleCoef);
		}
	}

	private class CookbookDelegateFlatGradientPainter extends
			StandardGradientPainter {
		@Override
		public Color getTopShineColor(
				SubstanceColorScheme interpolationScheme1,
				SubstanceColorScheme interpolationScheme2, double cycleCoef,
				boolean useCyclePosAsInterpolation) {
			return null;
		}

		@Override
		public Color getBottomShineColor(
				SubstanceColorScheme interpolationScheme1,
				SubstanceColorScheme interpolationScheme2, double cycleCoef,
				boolean useCyclePosAsInterpolation) {
			return null;
		}

		@Override
		public Color getTopFillColor(SubstanceColorScheme interpolationScheme1,
				SubstanceColorScheme interpolationScheme2, double cycleCoef,
				boolean useCyclePosAsInterpolation) {
			if (!useCyclePosAsInterpolation)
				return interpolationScheme1.getLightColor();
			return CookbookSkin.getInterpolatedRGB(interpolationScheme1
					.getLightColor(), interpolationScheme2.getLightColor(),
					cycleCoef);
		}

		@Override
		public Color getMidFillColorTop(
				SubstanceColorScheme interpolationScheme1,
				SubstanceColorScheme interpolationScheme2, double cycleCoef,
				boolean useCyclePosAsInterpolation) {
			if (!useCyclePosAsInterpolation)
				return interpolationScheme1.getMidColor();
			return CookbookSkin.getInterpolatedRGB(interpolationScheme1
					.getMidColor(), interpolationScheme2.getMidColor(),
					cycleCoef);
		}

		@Override
		public Color getMidFillColorBottom(
				SubstanceColorScheme interpolationScheme1,
				SubstanceColorScheme interpolationScheme2, double cycleCoef,
				boolean useCyclePosAsInterpolation) {
			return this
					.getMidFillColorTop(interpolationScheme1,
							interpolationScheme2, cycleCoef,
							useCyclePosAsInterpolation);
		}

		@Override
		public Color getBottomFillColor(
				SubstanceColorScheme interpolationScheme1,
				SubstanceColorScheme interpolationScheme2, double cycleCoef,
				boolean useCyclePosAsInterpolation) {
			if (!useCyclePosAsInterpolation)
				return interpolationScheme1.getDarkColor();
			return CookbookSkin.getInterpolatedRGB(interpolationScheme1
					.getDarkColor(), interpolationScheme2.getDarkColor(),
					cycleCoef);
		}
	}

	public CookbookGradientPainter() {
		this.delegate = new CookbookDelegateGradientPainter();
		this.flatDelegate = new CookbookDelegateFlatGradientPainter();
	}

	@Override
	public void paintContourBackground(Graphics g, Component comp, int width,
			int height, Shape contour, boolean isFocused,
			SubstanceColorScheme colorScheme1,
			SubstanceColorScheme colorScheme2, float cyclePos,
			boolean hasShine, boolean useCyclePosAsInterpolation) {
		if (comp instanceof JScrollBar) {
			this.flatDelegate.paintContourBackground(g, comp, width, height,
					contour, isFocused, colorScheme1, colorScheme2, cyclePos,
					hasShine, useCyclePosAsInterpolation);
			return;
		}

		this.delegate.paintContourBackground(g, comp, width, height, contour,
				isFocused, colorScheme1, colorScheme2, cyclePos, hasShine,
				useCyclePosAsInterpolation);

		if (comp instanceof AbstractCommandButton) {
			// special case - overlay the buttons with the watermark image
			// that corresponds to the decoration area of that button
			AbstractCommandButton commandButton = (AbstractCommandButton) comp;
			if (!commandButton.getActionModel().isSelected()
					&& !commandButton.getActionModel().isPressed()) {
				DecorationAreaType decorationAreaType = SubstanceLookAndFeel
						.getDecorationType(comp);
				SubstanceDecorationPainter decoPainter = SubstanceLookAndFeel
						.getCurrentSkin(comp).getDecorationPainter();
				if (decoPainter instanceof CookbookDecorationPainter) {
					BufferedImage watermark = ((CookbookDecorationPainter) decoPainter)
							.getWatermarkImage(decorationAreaType);
					Graphics2D g2d = (Graphics2D) g.create();
					g2d.clip(contour);
					g2d.setComposite(AlphaComposite.SrcOver.derive(0.3f));
					int dx = comp.getLocationOnScreen().x;
					int dy = comp.getLocationOnScreen().y;
					g2d.drawImage(watermark, -dx, -dy, null);
				}
			}
		}
	}

	@Override
	public String getDisplayName() {
		return "Cookbook";
	}

}
